package com.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dao.IBaseDao;
import com.tools.Page;
import com.tools.ParamType;

public class BaseDao<T> implements IBaseDao<T> {

	
	protected  final Logger log = LoggerFactory.getLogger(this.getClass());
	
	
	
	protected SessionFactory sessionFactory;
	

	public Session getSession() {
		log.info("获得session");
		return sessionFactory.getCurrentSession();
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		log.info("注入sessionFactory");
		this.sessionFactory = sessionFactory;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.dao.impl.IBaseDao#save(T)
	 */
	@Override
	public void save(T t) {
		log.info("保存对象"+t.getClass()+t);
		getSession().save(t);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.dao.impl.IBaseDao#delete(T)
	 */
	@Override
	public void delete(T t) {
		log.info("删除对象"+t.getClass()+t);
		getSession().delete(t);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.dao.impl.IBaseDao#update(T)
	 */
	@Override
	public void update(T t) {
		log.info("更新对象"+t.getClass()+t);
		getSession().update(t);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.dao.impl.IBaseDao#findByParams(java.lang.Class,
	 * com.tools.ParamType)
	 */
	@Override
	public T findByParams(Class<T> entityClass, ParamType... params) {
		
		log.info("查询一个对象"+entityClass);
		
		// 初始语句
		String hql = "select u from " + entityClass.getSimpleName() + " u ";

		// 取出需要查询的参数
		List<ParamType> findList = null;

		for (ParamType paramType : params) {
			if (paramType.getFind()) {
				if (findList == null) {
					findList = new ArrayList<>();
				}
				findList.add(paramType);
			}
		}

		// 有条件
		if (findList != null && findList.size() > 0) {
			hql += " where ";
			// 设置参数位置
			for (int i = 0; i < findList.size(); i++) {
				hql += " u." + findList.get(i).getName() + " " + findList.get(i).getRelaType() + " ? ";
				if (i != findList.size() - 1) {
					hql += " " + findList.get(i).getLogicType() + " ";
				}

			}
		}
		

		// 获得查询对象
		Query<T> query = getSession().createQuery(hql, entityClass);

		// 设置参数值
		for (int i = 0; i < findList.size(); i++) {
			query = query.setParameter(i,findList.get(i).getParam());
		}

		// 返回结果
		return query.getSingleResult();
	}
	
	

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.dao.impl.IBaseDao#getByParams(java.lang.Class,
	 * com.tools.ParamType)
	 */
	@Override
	public List<T> getByParams(Class<T> entityClass, Page page, ParamType... params) {

		log.info("查询一组对象"+entityClass);
		
		// 初始语句
		String hql = "select u from " + entityClass.getSimpleName() + " u ";

		// 取出需要查询的参数
		List<ParamType> findList = null;

		for (ParamType paramType : params) {
			if (paramType.getFind()) {
				if (findList == null) {
					findList = new ArrayList<>();
				}
				findList.add(paramType);
			}
		}

		// 有条件
		if (findList != null && findList.size() > 0) {
			hql += " where ";
			// 设置参数位置
			for (int i = 0; i < findList.size(); i++) {
				hql += " u." + findList.get(i).getName() + " " + findList.get(i).getRelaType() + " ? ";
				if (i != findList.size() - 1) {
					hql += " " + findList.get(i).getLogicType() + " ";
				}

			}
		}

		// 取出需要排队的参数
		List<ParamType> sortList = null;

		for (ParamType paramType : params) {
			if (paramType.getSort() != null) {
				if (sortList == null) {
					sortList = new ArrayList<>();
				}
				sortList.add(paramType);
			}
		}

		// 设置排序参数
		if (sortList != null && sortList.size() > 0) {
			hql += " order by ";
			for (int i = 0; i < sortList.size(); i++) {
				hql += " " + sortList.get(i).getName() + " " + sortList.get(i).getSort();
				if (i != sortList.size() - 1) {
					hql += " , ";
				}
			}
		}

		System.out.println(hql);

		// 获得查询对象
		Query<T> query = getSession().createQuery(hql, entityClass);

		if (findList != null && findList.size() > 0) {
			// 设置参数
			for (int i = 0; i < findList.size(); i++) {
				Object obj;
				if (ParamType.RELA_TYPE_LIKE.equals(findList.get(i).getRelaType())) {
					obj = "%" + findList.get(i).getParam() + "%";
				} else {
					obj = findList.get(i).getParam();
				}

				query = query.setParameter(i, obj);

			}
		}

		// 设置分页参数
		if(page!=null){
			query = query.setFirstResult((int) page.getIndex());
			query = query.setMaxResults((int) page.getSize());
		}
		

		// 返回结果
		return query.getResultList();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.dao.impl.IBaseDao#findCount(java.lang.Class,
	 * com.tools.ParamType)
	 */
	@Override
	public Long count(Class<T> entityClass, ParamType... params) {
		
		log.info("查询指定条件的记录数"+entityClass);
		
		// 初始语句
		String hql = "select count(u) from " + entityClass.getSimpleName() + " u ";

		// 取出需要查询的参数
		List<ParamType> findList = null;

		for (ParamType paramType : params) {
			if (paramType.getFind()) {
				if (findList == null) {
					findList = new ArrayList<>();
				}
				findList.add(paramType);
			}
		}

		// 有条件
		if (findList != null && findList.size() > 0) {
			hql += " where ";
			// 设置参数位置
			for (int i = 0; i < findList.size(); i++) {
				hql += " " + findList.get(i).getName() + " " + findList.get(i).getRelaType() + " ? ";
				if (i != findList.size() - 1) {
					hql += " " + findList.get(i).getLogicType() + " ";
				}

			}
		}

		System.out.println(hql);

		// 获得查询对象
		Query<Long> query = getSession().createQuery(hql, Long.class);

		// 设置参数
		for (int i = 0; i < findList.size(); i++) {
			Object obj;
			if (ParamType.RELA_TYPE_LIKE.equals(findList.get(i).getRelaType())) {
				obj = "%" + findList.get(i).getParam() + "%";
			} else {
				obj = findList.get(i).getParam();
			}

			query = query.setParameter(i, obj);

		}

		// 返回结果
		return query.getSingleResult();
	}

	@Override
	public List<T> getByParams(Class<T> entityClass, ParamType... params) {
		 return getByParams(entityClass, null, params);
	}

}
